package com.yanqu.road.server.manager.unionwar;

import com.yanqu.road.entity.activity.ActivityConditionInfo;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.unionwar.cross.CrossUnionWarDetail;
import com.yanqu.road.entity.enums.eUnionWarWinMark;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.rank.UnionActivityRank;
import com.yanqu.road.entity.unionwar.ConditionAchieveInfo;
import com.yanqu.road.entity.unionwar.CrossUnionGuessData;
import com.yanqu.road.logic.bussiness.activity.UnionWarActivityBusiness;
import com.yanqu.road.logic.cross.CrossUnionWarRankListModel;
import com.yanqu.road.logic.helper.UnionActivityGroupHelper;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.pb.activity.unionwar.UnionWarActivityServerProto;
import com.yanqu.road.pb.player.PlayerProto;
import com.yanqu.road.server.CrossBaseServer;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.union.activitygroup.Cross2UnionActivityGroupMgr;
import com.yanqu.road.server.protocol.GameProtocol;
import com.yanqu.road.utils.YanQuMessageUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;


public class CrossUnionWarGuessMgr extends TempMgr {
    //activityId - stage
    private static Map<Integer, Map<Integer, List<CrossUnionWarGuessDataListModel>>> unionWarGuessDataListModelMap;

    //activityId - conditionId
    private static Map<Integer, Map<Integer, List<ConditionAchieveInfo>>> conditionAchieveInfoMap;  //竞猜奖励各个档位达成人数

    @Override
    public boolean reloadData() {
        unionWarGuessDataListModelMap = new ConcurrentHashMap<>();
        initUnionWarGuessDataListModelMap();
        return true;
    }

    public static CrossUnionWarGuessDataListModel getCrossUnionWarGuessDataListModel(int activityId, int stage, int groupId) {
        if (!unionWarGuessDataListModelMap.containsKey(activityId)) {
            synchronized (unionWarGuessDataListModelMap) {
                if (!unionWarGuessDataListModelMap.containsKey(activityId)) {
                    unionWarGuessDataListModelMap.put(activityId, new ConcurrentHashMap<>());
                }
            }
        }
        if (!unionWarGuessDataListModelMap.get(activityId).containsKey(stage)) {
            synchronized (unionWarGuessDataListModelMap) {
                if (!unionWarGuessDataListModelMap.get(activityId).containsKey(stage)) {
                    unionWarGuessDataListModelMap.get(activityId).put(stage, new ArrayList<>());
                }
            }
        }
        List<CrossUnionWarGuessDataListModel> list = unionWarGuessDataListModelMap.get(activityId).get(stage);
        CrossUnionWarGuessDataListModel model;
        synchronized (unionWarGuessDataListModelMap){
            for (int i = 0; i < list.size(); i++) {
                CrossUnionWarGuessDataListModel temp = list.get(i);
                if(groupId == temp.getGroupId()){
                    return temp;
                }
            }
            model = new CrossUnionWarGuessDataListModel(activityId, stage, groupId);
            list.add(model);
        }
        return model;
    }

    /**
     * 初始化群英争霸 竞猜热度数据
     */
    private static void initUnionWarGuessDataListModelMap() {
        Map<Integer, ActivityInfo> activityInfoMap = CrossUnionWarActivityMgr.getOpenActivityMap();
        List<Integer> activityIdList = new ArrayList<>();
        for (ActivityInfo activityInfo : activityInfoMap.values()) {
            activityIdList.add(activityInfo.getActivityId());
        }
        if(activityIdList.size() == 0){
            return;
        }

        //activityId - stage - groupId - userId
        Map<Integer, Map<Integer, Map<Integer, Map<Long, CrossUnionGuessData>>>> crossGuessDataModelMap = UnionWarActivityBusiness.getCrossGuessDataMap(activityIdList);

        for (Map.Entry<Integer, Map<Integer, Map<Integer, Map<Long, CrossUnionGuessData>>>> activityEntry : crossGuessDataModelMap.entrySet()) {
            int activityId = activityEntry.getKey();
            List<Integer> groupIdList = CrossUnionWarMgr.getGroupListByCrossServerId(activityId, CrossBaseServer.getInstance().getServerId());
            if (!unionWarGuessDataListModelMap.containsKey(activityEntry.getKey())) {
                unionWarGuessDataListModelMap.put(activityEntry.getKey(), new ConcurrentHashMap<>());
            }
            for (Map.Entry<Integer, Map<Integer, Map<Long, CrossUnionGuessData>>> stateEntry : activityEntry.getValue().entrySet()) {
                if (!unionWarGuessDataListModelMap.get(activityEntry.getKey()).containsKey(stateEntry.getKey())){
                    unionWarGuessDataListModelMap.get(activityEntry.getKey()).put(stateEntry.getKey(), new ArrayList<>());
                }
                for (Map.Entry<Integer, Map<Long, CrossUnionGuessData>> groupEntry : stateEntry.getValue().entrySet()) {
                    int groupId = groupEntry.getKey();
                    if(!groupIdList.contains(groupId)){
                        continue;
                    }
                    CrossUnionWarGuessDataListModel model = null;
                    for (CrossUnionWarGuessDataListModel tempModel : unionWarGuessDataListModelMap.get(activityId).get(stateEntry.getKey())) {
                        if(tempModel.getGroupId() == groupId){
                            model = tempModel;
                        }
                    }
                    if(model == null){
                        model = new CrossUnionWarGuessDataListModel(activityId, stateEntry.getKey(), groupId);
                        unionWarGuessDataListModelMap.get(activityId).get(stateEntry.getKey()).add(model);
                    }
                    model.setUnionGuessMap(groupEntry.getValue());
                }
            }
        }
    }

    /**
     * 玩家竞猜同步跨服
     * @param activityId    活动id
     * @param phase         阶段
     * @param serverId      服务器id
     * @param userId        玩家id
     * @param unionUidList  竞猜列表
     * @param playerBaseInfo
     */
    public static void changeUnionGuess(int activityId, int phase, long serverId, long userId, List<String> unionUidList, PlayerProto.PlayerBaseTempMsg playerBaseInfo) {
        int groupId = Cross2UnionActivityGroupMgr.getViewDataGroupId(activityId, userId);
        if(unionUidList.size() > 0){
            String unionUid = unionUidList.get(0);
            int tempGroupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, unionUid);
            if(groupId != tempGroupId){
                groupId = tempGroupId;
            }
        }
        CrossUnionWarGuessDataListModel guessDataListModel = getCrossUnionWarGuessDataListModel(activityId, phase, groupId);
        if (guessDataListModel == null) {
            synchronized (unionWarGuessDataListModelMap) {
                if (!unionWarGuessDataListModelMap.containsKey(activityId)) {
                    unionWarGuessDataListModelMap.put(activityId, new ConcurrentHashMap<>());
                }
                if (!unionWarGuessDataListModelMap.get(activityId).containsKey(phase)) {
                    unionWarGuessDataListModelMap.get(activityId).put(phase, new ArrayList<>());
                }
                boolean exist = false;
                for (CrossUnionWarGuessDataListModel model : unionWarGuessDataListModelMap.get(activityId).get(phase)) {
                    if(model.getGroupId() == groupId){
                        exist = true;
                    }
                }
                if(!exist){
                    CrossUnionWarGuessDataListModel dataListModel = new CrossUnionWarGuessDataListModel(activityId, phase, groupId);
                    unionWarGuessDataListModelMap.get(activityId).get(phase).add(dataListModel);
                }
            }
            guessDataListModel = getCrossUnionWarGuessDataListModel(activityId, phase, groupId);
        }
        if (guessDataListModel != null) {
            guessDataListModel.changeUnionGuess(serverId, userId, unionUidList, playerBaseInfo);
        }
    }

    /**
     * 开奖统计一下各个奖励档位达成的人数
     * @param activityId    活动ID
     * @param phase         阶段
     */
    public static void calcConditionAchieveCount(int activityId, int phase, int groupId) {
        conditionAchieveInfoMap = new ConcurrentHashMap<>();
        synchronized (conditionAchieveInfoMap) {
            int conditionType = 0;
            if (phase == 1) {
                conditionType = 1002;
            } else if (phase == 2) {
                conditionType = 1003;
            }
            CrossUnionWarGuessDataListModel model = getCrossUnionWarGuessDataListModel(activityId, phase, groupId);
            CrossUnionWarRankListModel crossUnionWarRankListModel = CrossUnionWarRankMgr.getCrossUnionWarRankListModel(activityId, phase, groupId);
            LinkedList<UnionActivityRank> rankList = null;
            if(crossUnionWarRankListModel != null){
                rankList = crossUnionWarRankListModel.getRankList();
            }
            for (Map.Entry<Long, CrossUnionGuessData> dataEntry : model.getUnionGuessMap().entrySet()) {
                CrossUnionGuessData userUnionWarGuessData = dataEntry.getValue();
                int guessScore = getGuessScore(rankList, userUnionWarGuessData, phase);
                List<ActivityConditionInfo> activityConditionInfoList = CrossUnionWarActivityMgr.getActivityConditionInfoList(activityId, conditionType);
                ActivityConditionInfo activityConditionInfo = null;
                //是否是达成参与奖励
                //add v5.2.4
                boolean lastCondition = false;
                if (activityConditionInfoList != null) {
                    activityConditionInfoList.sort(Comparator.comparing(o -> o.getParamList().get(3)));
                    Collections.reverse(activityConditionInfoList);
                    for (ActivityConditionInfo info : activityConditionInfoList) {
                        // 根据个数取到对应conditionInfo
                        if (info.getParamList().get(3).intValue() <= guessScore) {
                            activityConditionInfo = info;
                            if (info.getParamList().get(3).intValue() == 0) {
                                //参与奖，不下发userBaseInfo
                                lastCondition = true;
                            }
                            break;
                        }
                        if (info.getParamList().get(3).intValue() == 0) {
                            activityConditionInfo = info;
                            //参与奖，不下发userBaseInfo
                            lastCondition = true;
                        }
                    }
                }
                if (activityConditionInfo != null) {
                    if (!conditionAchieveInfoMap.containsKey(activityId)) {
                        conditionAchieveInfoMap.put(activityId, new ConcurrentHashMap<>());
                    }
                    if (!conditionAchieveInfoMap.get(activityId).containsKey(activityConditionInfo.getConditionId())) {
                        conditionAchieveInfoMap.get(activityId).put(activityConditionInfo.getConditionId(), new ArrayList<>());
                    }

                    ConditionAchieveInfo conditionAchieveInfo = null;
                    for (ConditionAchieveInfo achieveInfo : conditionAchieveInfoMap.get(activityId).get(activityConditionInfo.getConditionId())) {
                        if(achieveInfo.getGroupId() == groupId){
                            conditionAchieveInfo = achieveInfo;
                        }
                    }
                    if (conditionAchieveInfo == null) {
                        conditionAchieveInfo = new ConditionAchieveInfo();
                        conditionAchieveInfo.setActivityId(activityId);
                        conditionAchieveInfo.setConditionId(activityConditionInfo.getConditionId());
                        conditionAchieveInfo.setAchieveCount(0);
                        conditionAchieveInfo.setGroupId(groupId);
                        conditionAchieveInfo.setUserList(new ArrayList<>());
                        conditionAchieveInfoMap.get(activityId).get(activityConditionInfo.getConditionId()).add(conditionAchieveInfo);
                    }
                    conditionAchieveInfo.setAchieveCount(1 + conditionAchieveInfo.getAchieveCount());
                    if(!lastCondition) {
                        conditionAchieveInfo.getUserList().add(userUnionWarGuessData.getUserBaseInfo());
                    }
                }
            }
            syncAllGameServer(activityId, groupId);
        }
    }

    private static void syncAllGameServer(int activityId, int groupId) {
        ActivityInfo activityInfo = CrossUnionWarActivityMgr.getOpenActivity(activityId);
        if (activityInfo == null) {
            return;
        }
        syncOneGameServer(activityId, 0, groupId);
    }

    public static void syncOneGameServer(int activityId, long serverId, int groupId) {
        ActivityInfo activityInfo = CrossUnionWarActivityMgr.getOpenActivity(activityId);
        if (activityInfo == null) {
            return;
        }
//        List<Integer> groupIdList = CrossUnionWarMgr.getGroupListByServerId(activityId, serverId);
        UnionWarActivityServerProto.UnionWarConditionAchieveMsg.Builder syncMsg = UnionWarActivityServerProto.UnionWarConditionAchieveMsg.newBuilder();
        syncMsg.setActivityId(activityId);
        if(conditionAchieveInfoMap.get(activityId) != null) {
            for (Map.Entry<Integer, List<ConditionAchieveInfo>> entry : conditionAchieveInfoMap.get(activityId).entrySet()) {
                ConditionAchieveInfo info = null;
                for (ConditionAchieveInfo achieveInfo : entry.getValue()) {
                    if(groupId == achieveInfo.getGroupId()){
                        info = achieveInfo;
                    }
                }
                if(info == null){
                    continue;
                }
                UnionWarActivityServerProto.UnionWarConditionAchieveTemp.Builder temp = UnionWarActivityServerProto.UnionWarConditionAchieveTemp.newBuilder();
                temp.setConditionId(info.getConditionId());
                temp.setAchieveCount(info.getAchieveCount());
                temp.setGroupId(info.getGroupId());
                for (UserBaseInfo userBaseInfo : info.getUserList()) {
                    if (userBaseInfo != null) {
                        temp.addPlayerBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
                    }
                }
                syncMsg.addUnionWarConditionAchieve(temp);
            }
            if(syncMsg.getUnionWarConditionAchieveCount() > 0){
                if(serverId > 0){
                    MessageHelper.sendPacket(serverId, 0, YanQuMessageUtils.buildMessage(GameProtocol.S_UNION_WAR_SYNC_CONDITION_ACHIEVE, syncMsg));
                }else {
                    List<Long> serverIdList =  CrossUnionWarMgr.getServerListByGroupId(activityInfo, groupId);
                    for (long sid : serverIdList) {
                        MessageHelper.sendPacket(sid, 0, YanQuMessageUtils.buildMessage(GameProtocol.S_UNION_WAR_SYNC_CONDITION_ACHIEVE, syncMsg));
                    }
                }
            }
        }
    }

    /**
     * 计算玩家竞猜得分
     * @param rankList                  排行榜数据
     * @param userUnionWarGuessData     玩家竞猜数据
     * @param phase                     阶段
     * @return
     */
    public static int getGuessScore(LinkedList<UnionActivityRank> rankList, CrossUnionGuessData userUnionWarGuessData, int phase) {
        int score = 0;
        int n = 8;
        int groupId = Cross2UnionActivityGroupMgr.getGroupId(userUnionWarGuessData.getActivityId(), userUnionWarGuessData.getUserId());
        if (phase == 1) {
            //晋级n人
            ActivityInfo activityInfo = CrossUnionWarActivityMgr.getOpenActivity(userUnionWarGuessData.getActivityId());
            try {
                n = Integer.parseInt(activityInfo.getParam4().split(";")[2]);
            } catch (Exception e) {
                getLogger().error(e.getMessage(), e);
            }
            for (int i = 0; i < n; i++) {
                if (i >= rankList.size()) {
                    break;
                }
                UnionActivityRank rank = rankList.get(i);
                for (String guessUnionUid : userUnionWarGuessData.getUnionUid()) {
                    if (Objects.equals(guessUnionUid, rank.getUnionUid())) {
                        score ++;
                    }
                }
            }
        } else if (phase == 2) {
            //冠亚军
//            for (int i = 0; i < 2; i++) {
//                UnionActivityRank rank = rankList.get(i);
//                if (userUnionWarGuessData.getUnionUid().get(i) != null) {
//                    if (Objects.equals(userUnionWarGuessData.getUnionUid().get(i), rank.getUnionUid())) {
//                        score += i == 0 ? 2 : 1;
//                    }
//                }
//            }
            int allSession = CrossUnionWarActivityMgr.getAllSession(userUnionWarGuessData.getActivityId(), 2);
            List<CrossUnionWarDetail> detailList = CrossUnionWarMgr.getCrossUnionWarDetailList(userUnionWarGuessData.getActivityId(), 2, allSession, groupId);
            if(detailList != null){
                for(CrossUnionWarDetail detail : detailList){
                    if(detail.getWinMark() == eUnionWarWinMark.Win.getValue()){
                        if (userUnionWarGuessData.getUnionUid().size() >= 1) {
                            score += detail.getUnionUid().equals(userUnionWarGuessData.getUnionUid().get(0)) ? 2 : 0;
                        }
                    }else if(detail.getWinMark() == eUnionWarWinMark.Lose.getValue()){
                        if (userUnionWarGuessData.getUnionUid().size() >= 2) {
                            score += detail.getUnionUid().equals(userUnionWarGuessData.getUnionUid().get(1)) ? 1 : 0;
                        }
                    }
                }
            }
        }
        return score;
    }



    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean stop() {
        return false;
    }

    public boolean save() {
        for (Map<Integer, List<CrossUnionWarGuessDataListModel>> map : unionWarGuessDataListModelMap.values()) {
            for (Map.Entry<Integer, List<CrossUnionWarGuessDataListModel>> entry : map.entrySet()) {
                for (int i = entry.getValue().size() - 1; i >= 0; i--) {
                    CrossUnionWarGuessDataListModel dataListModel = entry.getValue().get(i);
                    dataListModel.save();
                }
            }
        }
        return true;
    }
}
